#include <iostream>
/*
普通指针 需要手动释放
有可能会忘记使用delete或者代码中有delete但因为中间过程抛出异常等导致运行逻辑中没有正确调用delete释放内存
造成内存泄漏的情况

智能指针 保证资源的自动释放
利用RAII原理，通过栈上的对象出作用域自动析构的特性，在析构函数中调用delete，以达到自动释放资源的目的。
*/

template <typename T>
class SmartPtr {
public:
    SmartPtr(T* ptr = nullptr) : _ptr(ptr) {
    }

    ~SmartPtr() {
        delete _ptr;
    }

    const T& operator*() const {
        return *_ptr;
    }

    T& operator*() {
        return *_ptr;
    }

    T* operator->() {
        return _ptr;
    }

private:
    T* _ptr;
};

class Foo {
public:
    Foo(int a) : _a(a) {
        std::cout << "Foo(int)" << std::endl;
    }

    ~Foo() {
        std::cout << "~Foo()" << std::endl;
    }

    int a() const {
        return _a;
    }

private:
    int _a;
};

int main() {
    SmartPtr<int> spi(new int(10));
    *spi = 20;
    std::cout << *spi << std::endl;

    SmartPtr<Foo> spf(new Foo(10));
    std::cout << (*spf).a() << std::endl;
    std::cout << spf->a() << std::endl;
    return 0;
}
